Xcode 16.0とiOS 18.0シミュレータの組み合わせでSafariViewControllerがフリーズしてしまう不具合を解消する

Xcode 16.0とiOS 18.0シミュレータの組み合わせでSafariViewControllerがフリーズしてしまう不具合を解消する

Clock Icon2024.09.27

Xcode 16.0とiOS 18.0シミュレータの組み合わせで、SFSafariViewControllerが表示されない不具合を発見した。

Xcode 16.0でビルドしたアプリでデバッグ実行し、SFSafariViewControllerを表示させようとした時に真っ白い画面になったり、閉じるボタンがステータスバーの裏側に入りこみ、アプリがフリーズしてしまう現象である。私はiOS 18.0シミュレータの不具合と考えているが、2024年9月27日時点では解消する目処が立っていない。

この問題の理由については明確ではないが、Xcodeのプロジェクト設定を調整することで正常に表示できるようになったため、不具合の原因と今後の対応について共有したい。

不具合の原因

Excluded ArchitecturesAny iOS Simulator SDKarm64を設定していると、iOS 18.0シミュレータのSFSafariViewControllerで正常に動作しなくなってしまう。この設定は以下のスクリーンショットの場所にある。

スクリーンショット 2024-09-27 12.35.00

project.pbxproj上では、以下のように表現されていることがある。また、Podfileで定義されている場合もある。

"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;

Appleシリコンを搭載したMacでは、シミュレーターがarm64アーキテクチャを使用している。IntelベースのMacではx86_64アーキテクチャを使用するため、この設定でarm64を除外することでシミュレーターが動作するようにしている。Intel MacからAppleシリコン Macへの移行時によく設定されていたかと思う。

不具合の発生するミニマムコード

問題が発生する最小構成のコードを以下に示す。ボタンをタップするとSafariViewControllerをラップしたSafariViewを表示するだけの簡単なコードである。

import SafariServices
import SwiftUI

struct SafariView: UIViewControllerRepresentable {
    let url = URL(string: "https://dev.classmethod.jp/")!

    func makeUIViewController(context _: Context) -> SFSafariViewController {
        let controller = SFSafariViewController(url: url)
        controller.dismissButtonStyle = .close
        controller.preferredControlTintColor = .green
        return controller
    }

    func updateUIViewController(_: SFSafariViewController, context _: Context) {}
}

struct ContentView: View {
    @State private var showSafariView = false

    var body: some View {
        VStack {
            Button(action: { showSafariView = true }) {
                Text("Open SafariView")
            }
        }
        .fullScreenCover(isPresented: $showSafariView) {
            SafariView()
        }
    }
}

#Preview {
    ContentView()
}

このコードをiOS 18シミュレータで実行したとき、EXCLUDED_ARCHSの設定によって挙動が異なる。EXCLUDED_ARCHSarm64を設定している場合、SFSafariViewControllerが真っ白く表示されたり、不正な表示になってしまう。

EXCLUDED_ARCHSでarm64が設定されている EXCLUDED_ARCHSの設定をしていない
EXCLUDED_ARCHSでarm64が設定されている場合にはSafariViewがフリーズする EXCLUDED_ARCHSの設定がなければSafriViewは正常に表示できる

まとめ

"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;を削除することで、Xcode 16.0とiOS 18.0シミュレータの組み合わせにおいても、SFSafariViewControllerを正常に動作させることができた。この問題はAppleによる不具合の可能性が高いと考えている。

今年の6月の時点でAppleデベロッパーフォーラムにて報告があったが、その時点では原因が特定されておらず、Appleのエンジニアも不具合の原因を特定できなかったのだろう。修正されずに iOS 18.0 Releaseがリリースされてしまったようだ。

解決策と今後の対応

サードパーティSDKの arm64 対応が進み、多くのアプリにおいては、"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;を削除しても正常に動作するケースが多いと思う。

ただし、特定のサードパーティSDKに依存している場合、簡単には解決しないかもしれない。以下の図のように、ライブラリがarm64を含むかどうかを確認する必要がある。上のライブラリでは、xcframeworkに ios-arm64_x86_64-simulatorが含まれており、arm64に対応しており問題がないことがわかる。

しかし、下のライブラリはios-x86_64-simulatorとなっており、arm64に対応していないことがわかる。このような事例の場合は、SDKの提供元に修正を依頼する必要がある。

スクリーンショット 2024-09-27 13.30.02

この不具合に関しては、昔からメンテナンスを続けてきたいわゆる「老舗」のアプリほど影響を受けるだろう。影響を受けるアプリも多いことが想定されるため、Appleの迅速な修正を期待しても良いかもしれない。iOS 18.0の実機やiOS 17.xシミュレータでは正常に動作するため、解決までの間は最小限の不便さで済むだろう。

関連するApple Developerフォーラムの課題は以下の通りだ。問題が解決するまでウォッチしたいと思う。

https://forums.developer.apple.com/forums/thread/764468

https://forums.developer.apple.com/forums/thread/756986

(2024/10/09追記) UIImagePickerControllerでも同様にフリーズする

本記事の中ではSFSafariViewControllerのことのみ記載したが、UIImagePickerController でも同様のフリーズする現象が発生することがわかった。React NativeとFlutterでも本事象についてのIssueが投稿されていた。

(2024/10/25追記) Xcode 16.1 RCでも修正されていない

先日、Xcode 16.1 Release Candidate と iOS 18.1 RCシミュレータが配信された。Xcode 16.1とiOS 18.1 RCシミュレータの組み合わせで調査したが問題は継続して発生していた。Appleとしてはこの現象について認識していると考えているが現時点では修正されていない。

2020年にAppleシリコンが登場してから4年が経過しており、Appleからするとx86_x64対応を残すメリットがないので、この問題の優先度が低いのかもしれない。

私が開発しているアプリでは、特定のサードパーティSDKに依存しているため、SDKの提供元にarm64対応を強くリクエストをしていきたいと考えている。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.